import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.*;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.*;
import org.apache.lucene.store.FSDirectory;
import org.lionsoul.jcseg.analyzer.v5x.JcsegAnalyzer5X;
import org.lionsoul.jcseg.tokenizer.core.JcsegTaskConfig;

public class Main {
    //存放索引的位置
    private  static String indexDirPath="/home/fengli/luceneIndex";
    //模拟标签库
    private static Map<String,String> marks=new HashMap<String, String>();
    static{
        marks.put("0","baidu");
        marks.put("1","google");
        marks.put("2","sougou");
        marks.put("3","firefox");
        marks.put("4","uc");
        marks.put("5","qq browser");
        marks.put("6","opera");
        marks.put("7","cu");
        marks.put("8","opera");
        marks.put("9","冯利");
        marks.put("10","已办");
        marks.put("11","未办");
        marks.put("12","dd");
    }

    public static void main(String[] args) throws Exception {
      /*  HashMap<String,String> result= (HashMap<String, String>) serachByStr("冯利",marks);
        for(String key:result.keySet()){
            System.out.println( "查询到========>"+"label:"+result.get(key)+"   id:"+key);
        }*/
        createIndex("/home/fengli/luceneIndex","/home/fengli/luceneData");
        serach("c.txt","/home/fengli/luceneIndex");
    }

    /**
     * 用于从dataDirPath生成索引，索引包括内容、路径
     *
     * @param indexDirPath
     * @param dataDirPath
     * @throws IOException
     */
    public static void createIndex(String indexDirPath, String dataDirPath) throws IOException {
        //indexDir is the directory that hosts Lucene's index files
        File indexDir = new File(indexDirPath);//"/home/fengli/luceneIndex"
        //dataDir is the directory that hosts the text files that to be indexed
        File dataDir = new File(dataDirPath);//"/home/fengli/luceneData"
        Analyzer luceneAnalyzer = new StandardAnalyzer();
        //Analyzer analyzer=new  SmartChineseAnalyzer();
        File[] dataFiles = dataDir.listFiles();
        IndexWriter indexWriter = new IndexWriter(indexDir, luceneAnalyzer, true);
        long startTime = new Date().getTime();
        for (int i = 0; i < dataFiles.length; i++) {
            if (dataFiles[i].isFile() && dataFiles[i].getName().endsWith(".txt")) {
                System.out.println("Indexing file " + dataFiles[i].getCanonicalPath());
                Document document = new Document();
                Reader txtReader = new FileReader(dataFiles[i]);
                document.add(Field.Text("path", dataFiles[i].getCanonicalPath()));
                document.add(Field.Text("contents", txtReader));
                indexWriter.addDocument(document);
            }
        }
        indexWriter.optimize();
        indexWriter.close();
        long endTime = new Date().getTime();

        System.out.println("It takes " + (endTime - startTime)
                + " milliseconds to create index for the files in directory "
                + dataDir.getPath());
    }

    /**
     * 从指定索引路径查询字符串
     *
     * @param queryStr
     * @param indexDirPath
     * @throws IOException
     */
    public static void serach(String queryStr, String indexDirPath) throws IOException {
        //This is the directory that hosts the Lucene index
        File indexDir = new File(indexDirPath); //"/home/fengli/luceneIndex"
        FSDirectory directory = FSDirectory.getDirectory(indexDir, false);
        IndexSearcher searcher = new IndexSearcher(directory);
        if (!indexDir.exists()) {
            System.out.println("The Lucene index is not exist");
            return;
        }
        Term term = new Term("contents", queryStr.toLowerCase());
        TermQuery luceneQuery = new TermQuery(term);
        Hits hits = searcher.search(luceneQuery);
        for (int i = 0; i < hits.length(); i++) {
            Document document = hits.doc(i);
            System.out.println("File: " + document.get("path"));
        }
    }

    /**
     * 字符组合方式
     *
     * @param chs   字符数组
     * @param start 开始位置
     * @param len   结束位置
     * @param dest  结果
     */
    public static void arrange(char[] chs, int start, int len, ArrayList<String> dest) {
        if (start == len - 1) {
            //装结果
            dest.add(new String(chs));
            return;
        }
        for (int i = start; i < len; i++) {
            char temp = chs[start];
            chs[start] = chs[i];
            chs[i] = temp;
            arrange(chs, start + 1, len, dest);
            temp = chs[start];
            chs[start] = chs[i];
            chs[i] = temp;
        }
    }

    /**
     * 从Map中创建索引
     * @param marks 标签库
     * @param indexDirPath 索引路径
     * @throws IOException
     */
    public static void createIndextFromMap(Map<String, String> marks, String indexDirPath) throws IOException {
        //indexDir is the directory that hosts Lucene's index files
        File indexDir = new File(indexDirPath);//"/home/fengli/luceneIndex"

        Analyzer luceneAnalyzer = new StandardAnalyzer();
        //Analyzer luceneAnalyzer = new JcsegAnalyzer5X(JcsegTaskConfig.SIMPLE_MODE);
        //Analyzer
        IndexWriter indexWriter = new IndexWriter(indexDir, luceneAnalyzer, true);
        long startTime = new Date().getTime();
        for (String key : marks.keySet()) {
            Document document = new Document();
            document.add(Field.Text("id", key));
            document.add(Field.Text("label", marks.get(key)));
            indexWriter.addDocument(document);
        }
        indexWriter.optimize();
        indexWriter.close();
        long endTime = new Date().getTime();

        System.out.println("It takes " + (endTime - startTime)
                + " milliseconds to create index for the files in marks(Map) "
        );

    }

    /**
     * 从索引中查找满足conditions 任意一个条件的结果
     * @param conditions
     * @param indexDirPath
     */
    public static Map<String, String> serachByArrayList(ArrayList<String> conditions, String indexDirPath) throws IOException {
        //This is the directory that hosts the Lucene index
        File indexDir = new File(indexDirPath); //"/home/fengli/luceneIndex"
        FSDirectory directory = FSDirectory.getDirectory(indexDir, false);
        IndexSearcher searcher = new IndexSearcher(directory);
        if (!indexDir.exists()) {
            System.out.println("The Lucene index is not exist");
            return null;
        }
        BooleanQuery booleanQuery = new BooleanQuery();
        for(int i=0;i<conditions.size();++i){
            TermQuery termQuery = new TermQuery(new Term("label", conditions.get(i)));
            booleanQuery.add(termQuery, BooleanClause.Occur.SHOULD);
        }
        Hits hits = searcher.search(booleanQuery);
        //将hit封装为Map返回
        Map<String,String> destMap=new HashMap();
        for(int i=0;i<hits.length();++i){
            Document document = hits.doc(i);
            destMap.put(hits.doc(i).get("id"),hits.doc(i).get("label"));
        }
        return destMap;
    }

    public static Map<String,String> serachByStr(String str,Map<String,String> marks) throws IOException {
        //创建索引
        createIndextFromMap(marks,"/home/fengli/luceneIndexMap");
        //获取查询条件
        ArrayList<String> conditions=new ArrayList<String>();
        char[] input =str.toCharArray();
        arrange(input,0,input.length,conditions);
        //查询
        HashMap<String,String> result= (HashMap<String, String>) serachByArrayList(conditions,"/home/fengli/luceneIndexMap");
        return  result;
    }
}
